/**
* @file parseparam.c
*
* @author Jan Sliacky
*
* Lib to parsing input parameters
*
* April 2010
*
* Copyright (c) 2010 by Jan Sliacky
* All rights reserved.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <libgen.h>
#include <getopt.h>
#include "globals.h"

/**
 * Print usage of program
 * @author Jan Sliacky
 * @param prog	program path
 */
void usage(char* prog) {
    printf("Usage:\n%s gen-input -o <output file> [options]\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n\n", basename(prog),
           "	-i <source file>",
           "	-c <count of processors cores>",
           "	-d <latency of sends and broadcasts>",
           "	-a <amount of solved tasks in package>",
           "	-f <forget task statuses after fall>",
           "	-g <get all unassign tasks immediately>",
           "	-p <procs count>",
           "	-t <tasks count>",
           "	-T <mu of tasks complexities>",
           "	-U <sigma of tasks complexities>",
           "	-P <mu of fall time>",
           "	-R <sigma of fall time>",
           "	-D <mu of fall duration>",
           "	-E <sigma of fall duration>",
           " 	-S <sigma of next fall>",
           "	-l <log level>,",
           "	-h print help");
   // printf("%s gen-stats\n", basename(prog));
    printf("%s run <input_file>\n\n", basename(prog));
}

/**
 * Parse command line and fill input configuration variable
 * @author Jan Sliacky
 * @param 	conf	input configuration parameters
 * @param	argc	number of cmd input parameters
 * @param	argv	cmd input parameters
 * @return	input configuration parameters
 */
init_config* parseInputOptions(init_config* conf, int argc, char **argv) {
    char opt;

    if(argc == 2) {
        usage(argv[0]);
        exit(EXIT_SUCCESS);
    }
    conf->sourceFile = NULL;
    conf->outputFile = NULL;
    conf->nHwCores = -1;
    conf->amount = no_amount;
    conf->forgetStatuses = -1;
    conf->takeAll = -1;
    conf->nProcs = -1;
    conf->nTasks = -1;
    conf->muTasks = -1;
    conf->sigTasks = -1;
    conf->muFallProb = -1;
    conf->sigFallProb = -1;
    conf->muFallDur = -1;
    conf->sigFallDur = -1;
    conf->sigNextFall = -1;
    conf->logLevel = no_level;

    while ((opt = getopt(argc, argv, "hi:o:c:d:a:f:g:p:t:T:U:P:R:D:E:S:l:")) != EOF) {
        switch (opt) {
        case 'h': /* help */
            usage(argv[0]);
            exit(EXIT_SUCCESS);
            break;
        case 'i': /* */
            conf->sourceFile = optarg;
            break;
        case 'o': /* */
            conf->outputFile = optarg;
            break;
        case 'c': /* */
            conf->nHwCores = atoi(optarg);
            break;
        case 'd': /* */
            conf->latency = atof(optarg);
            break;
        case 'a': /* */
            if (strcmp(optarg,"one") == 0) {
                conf->amount = one;
            } else
                if (strcmp(optarg,"npart") == 0) {
                    conf->amount = npart;
                } else
                    if (strcmp(optarg,"all") == 0) {
                        conf->amount = all;
                    }
            break;
        case 'f': /* */
            conf->forgetStatuses = atoi(optarg);
            break;
        case 'g': /* */
            conf->takeAll = atoi(optarg);
            break;
        case 'p': /* */
            conf->nProcs = atoi(optarg);
            break;
        case 't': /* */
            conf->nTasks = atoi(optarg);
            break;
        case 'T': /* */
            conf->muTasks = atof(optarg);
            break;
        case 'U': /* */
            conf->sigTasks = atof(optarg);
            break;
        case 'P': /* */
            conf->muFallProb = atof(optarg);
            break;
        case 'R': /* */
            conf->sigFallProb = atof(optarg);
            break;
        case 'D': /* */
            conf->muFallDur = atof(optarg);
            break;
        case 'E': /* */
            conf->sigFallDur = atof(optarg);
            break;
        case 'S': /* */
            conf->sigNextFall = atof(optarg);
            break;
        case 'l': /* */
            if (strcmp(optarg,"trace")==0) {
                conf->logLevel = trace;
            } else
                if (strcmp(optarg,"debug")==0) {
                    conf->logLevel = debug;
                } else
                    if (strcmp(optarg,"msg")==0) {
                        conf->logLevel = msg;
                    } else
                        if (strcmp(optarg,"info")==0) {
                            conf->logLevel = info;
                        } else
                            if (strcmp(optarg,"error")==0) {
                                conf->logLevel = error;
                            } else
                                if (strcmp(optarg,"none")==0) {
                                    conf->logLevel = none;
                                }
            break;
        case '?':
            if (strchr("i:o:c:d:a:f:g:p:t:T:U:P:R:D:E:S:l:", optopt) != NULL ) {
                fprintf(stderr, "Error - Option `%c' needs a value\n\n", optopt);
            } else {
                fprintf (stderr, "Unknown option `-%c'.\n\n", optopt);
            }
            exit(EXIT_FAILURE);
        }
    }
    if(conf->outputFile == NULL) {
        fprintf (stderr, "Output file parameter -o is mandatory\n\n");
        exit(EXIT_FAILURE);
    }
    return conf;
}

/**
 * Parse command line and fill statistics configuration variable
 * @author Jan Sliacky
 * @param 	conf	statistics configuration parameters
 * @param	argc	number of cmd statistics parameters
 * @param	argv	cmd input parameters
 * @return	statistics configuration parameters
 */
stats_config* parseStatsOptions(stats_config* conf, int argc, char **argv) {
    return conf;
}
